home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
076-100
/
scopedisk83
/
popcli4
/
cback.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
4KB
|
150 lines
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1988 The Software Distillery. All Rights Reserved */
/* |. o.| || This program may not be distributed without the permission of */
/* | . | || the authors. */
/* | o | || Dave Baker Ed Burnette Stan Chow Jay Denebeim */
/* | . |// Gordon Keener Jack Rouse John Toebes Doug Walker */
/* ====== BBS:(919)-471-6436 VOICE:(919)-469-4210 */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* C version of a new cback.a for PopCLI */
/* This code should be put in the throwaway segment. It will clone the */
/* second segment of this process into an independent seglist, and do */
/* a CreateProc for it. */
#include <exec/types.h>
#include <exec/alerts.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/tasks.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <workbench/startup.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include "cback.h"
/* Constants for the new process: */
#define PROCNAME "PopCLI IV"
#define STACKSIZE 4096
#define PRIORITY 20
struct Segment {
ULONG sm_len;
BPTR sm_next;
};
/* Get a Task pointer from the MsgPort pointer returned by CreateProc */
#define GETTASK(m) (((struct Task *)m)-1)
void __far _main(void);
void __asm start(register __a0 char *cmd, register __d0 char *cmdlen)
{
struct DosLibrary *DOSBase;
struct Process *us;
struct MemList memlist, *ml;
struct Segment *segment;
char *newseg;
struct cbackstr *msg;
BPTR cwd;
int sig;
struct MsgPort *procmsg;
struct WBStartup *wbmsg;
BPTR stdin;
DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
us = (struct Process *)FindTask(0);
msg = AllocMem( sizeof(struct cbackstr),
MEMF_PUBLIC|MEMF_CLEAR );
msg->msgpart.mn_Length = sizeof(struct cbackstr);
cwd = us->pr_CurrentDir;
if (us->pr_CLI)
{
/* Run from CLI. We need to duplicate the lock for the */
/* current working directory. */
cwd = DupLock(cwd);
/* Find the _main()'s segment. We need to clone it */
/* KLUDGE WARNING: to find _main's segment, back up 8 */
/* bytes from the address of _main. */
segment = (struct Segment *) (((char *)_main)-8);
memlist.ml_NumEntries = 1;
memlist.ml_ME[0].me_Reqs = MEMF_PUBLIC;
memlist.ml_ME[0].me_Length = segment->sm_len;
ml = AllocEntry( &memlist );
newseg = (char *) ml->ml_ME[0].me_Addr;
memcpy( newseg, (char *)(&(segment->sm_next)),
segment->sm_len );
*((long *)newseg) = 0;
/* set up the message fields we now need */
msg->stdout = Open("*", MODE_OLDFILE);
msg->SyncProcess = us;
msg->SyncSignal = sig = AllocSignal(-1);
msg->cmd = cmd;
msg->cmdlen = cmdlen;
/* Start up the new proc */
Forbid();
procmsg = CreateProc(
PROCNAME,
PRIORITY,
(BPTR)((ULONG)newseg>>2),
STACKSIZE
);
if (procmsg)
{
AddTail( &(GETTASK(procmsg)->tc_MemEntry),
(struct Node *)ml );
}
Permit();
/* Let 'em go, but wait until they let us go */
if (procmsg && sig >= 0)
{
PutMsg( procmsg, (struct Message *)msg );
Wait(1<<sig);
}
}
else
{
/* We're a WorkBench process. Don't fork, but get the */
/* workbench message and use stuff from it. */
WaitPort( &us->pr_MsgPort );
wbmsg = (struct WBStartup *)GetMsg( &us->pr_MsgPort );
cwd = CurrentDir( wbmsg->sm_ArgList->wa_Lock );
/* Stuff to get cmdline & stuff */
stdin = Open( wbmsg->sm_ToolWindow, MODE_OLDFILE );
/* Send ourselves the message, since we're going to be */
/* waiting for it */
PutMsg( &us->pr_MsgPort, (struct Message *)msg );
/* Call the main routine */
_main();
Close(stdin);
/* Forbid(); is this really necessary???? */
ReplyMsg((struct Message *)wbmsg);
}
UnLock(cwd);
CloseLibrary((struct Library *)DOSBase);
}